package edu.neumont.MillerK.Web.DBQueries;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.persistence.Cache;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceUnit;
import javax.persistence.PersistenceUnitUtil;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.metamodel.Metamodel;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;

import edu.neumont.MillerK.POJOs.Security;
import edu.neumont.MillerK.Web.Entities.Location;
import edu.neumont.MillerK.Web.Entities.User;

public class DBQueries {
	
	private UserTransaction userTransaction;
	private EntityManagerFactory entityManagerFactory;
	
	public DBQueries(EntityManagerFactory emf, UserTransaction utx){
		entityManagerFactory = emf;
		userTransaction = utx;
	}
	
	public void createUser(User newUser){
		try{
			userTransaction.begin();
			getManager().persist(newUser);
			userTransaction.commit();
		}catch(Exception e){
			try{
				userTransaction.rollback();
			}catch(Exception e2){
				System.out.println("Rollback problem - " + e2.getMessage());
			}
		}
	}
	
	public List<User> getAllUsers(){
		TypedQuery<User> usersQuery = getManager().createQuery("select u from User u", User.class);
		ArrayList<User> users = new ArrayList<User>();
		users.addAll(usersQuery.getResultList());
		return users;
	}
	
	public List<String> getAllEmailUsernames(){
		TypedQuery<String> emailUsernamesQuery = getManager().createQuery("SELECT u.emailUsername FROM User u", String.class);
		ArrayList<String> emailUsernames = new ArrayList<String>();
		emailUsernames.addAll(emailUsernamesQuery.getResultList());
		return emailUsernames;
	}
	
	public User getUser(String emailUsername){
		TypedQuery<User> user = getManager().createQuery("SELECT u FROM User u WHERE u.emailUsername='" + emailUsername + "'", User.class);
		try{
			return user.getSingleResult();
		}catch(NoResultException noResult){
			return null;
		}
	}
	
	public void updateUserLocations(User user, Location location){
		try{
			userTransaction.begin();
			User updateUser = user;
			updateUser.getGpsLocations().add(location);
			getManager().merge(updateUser);
			userTransaction.commit();
		}catch(Exception e){
			try {
				userTransaction.rollback();
			} catch (Exception e1) {
				System.out.println("User update GPS Locations Rollback failed... " + e1.getMessage());
			}
		}
	}
	
	public void updateUserCommands(User user, char[] commands){
		try{
			userTransaction.begin();
			User updateUser = user;
			updateUser.setCommands(charArrayToString(commands));
			getManager().merge(updateUser);
			userTransaction.commit();
		}catch(Exception e){
			try {
				userTransaction.rollback();
			} catch (Exception e1) {
				System.out.println("User update features Rollback failed... " + e1.getMessage());
			}
		}
	}
	
	public void updateUserFeatures(User user, String features){
		try{
			userTransaction.begin();
			User updateUser = user;
			updateUser.setFeatures(features);
			getManager().merge(updateUser);
			userTransaction.commit();
		}catch(Exception e){
			try {
				userTransaction.rollback();
			} catch (Exception e1) {
				System.out.println("User update features Rollback failed... " + e1.getMessage());
			}
		}
	}
	
	private EntityManager getManager(){
		return entityManagerFactory.createEntityManager();
	}
	
	private String charArrayToString(char[] chars){
		String charString = "";
		for(char c : chars){
			charString += c;
		}
		return charString;
	}
}
